package main;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.LinkedList;

import entity.Attackable;
import entity.DynamicEntity;
import entity.Entity;
import math.Vector2D;
import entity.building.Building;
import entity.units.*;

/**
 * 
 * @author Greg Giannone
 * 
 * This class is used to store all the entities and perform certain
 * operations on them
 *
 */

public class GameList
{
	private LinkedList<Entity> ents;
	
	public GameList()
	{
		ents = new LinkedList<Entity>();
	}
	
	public LinkedList<Entity> getList()
	{
		return ents;
	}
	
	public void add( Entity en )
	{
		if( en instanceof AirUnit )
			ents.addFirst( en );
		else
			ents.add( en );
	}
	
	public Entity get( int i )
	{
		return ents.get(i);
	}
	
	public void remove( Entity e )
	{
		ents.remove( e );
	}
	
	/**
	 * See if an entity exists in the game list
	 * @param e
	 * @return
	 */
	public boolean contains(Entity e)
	{
		return ents.contains( e );
	}
	
	/**
	 * returns the closest entity of class c
	 */
	public <T extends Entity> T getClosest(Vector2D vec, Class<T> c)
	{
		double dist = -1;
		int index = -1;
		for (int i = 0; i < ents.size(); i++)
		{
			Entity e = ents.get(i);
			
			double newDist = vec.distance(e.getPosition());
			if ( c.isInstance( e ) && ( newDist <= dist || dist < 0 ) )
			{
				dist = newDist;
				index = i;
			}
		}
		if (index >= 0)
			return (T)ents.get(index);
		return null;
	}
	
	public <T extends Entity> LinkedList<T> getWithinRange( Vector2D center, double range, Class<T> c )
	{
		LinkedList<T> entities = new LinkedList<T>();
		
		for( Entity e : ents )
		{
			if( e.getPosition().distance( center ) <= range && c.isInstance( e ) )
				entities.add( (T)e );
		}
		
		return entities;
	}
	
	public Entity select( Vector2D v )
	{
		for( Entity e : ents )
		{
			if( e.getBounds().contains( v.getX(), v.getY() ) )
				return e;
		}
		
		return null;
	}
	
	public LinkedList<DynamicEntity> select( Rectangle r )
	{
		LinkedList<DynamicEntity> list = new LinkedList<DynamicEntity>();
		
		for( Entity e : ents )
		{
			if( e instanceof DynamicEntity && r.contains( e.getPosition().getX(), e.getPosition().getY() ) )
				list.add( (DynamicEntity)e );
		}
		
		return list;
	}
	
	public void update( double duration )
	{
		Entity e;
		for( int i = 0; i < ents.size(); i++ )
		{
			e = ents.get( i );
			
			if( e instanceof Attackable && ((Attackable)e).isDead() )
			{
				if( e instanceof Building)
					((Building)e).resetNodes();
				
				ents.remove( e );
			}
			else
				e.update( duration );
		}
	}
	
	public void render( Graphics2D g )
	{
		for( Entity e : ents )
		{
			e.draw( g );
		}
	}
}

